﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Player.Fort
{
    public class FortHP
    {
        public event Action<FortHP> EventOnHpChange;
        public event Action EventOnDeath;

        public bool IsDeath { get; private set; }
        private float _fCurHp, _fMaxHp, _fHPS_Fixed, _fHPS_Percent, _fShild_Fixed, _fShild_Percent;

        //计算后的百分比回血，避免反复运算
        public float CurHPS_Percent { get; private set; } = 0;

        private bool _bNeedRefresh = false;

        /// <summary>
        /// 当前每秒回血
        /// </summary>
        public float HPS_Fixed
        {
            get => _fHPS_Fixed;
            set
            {
                _fHPS_Fixed = value;

                _bNeedRefresh = true;
            }
        }
        /// <summary>
        /// 百分比回血
        /// </summary>
        public float HPS_Percent
        {
            get => _fHPS_Percent;
            set
            {
                _fHPS_Percent = value;
                CurHPS_Percent = MaxHp * _fHPS_Percent;

                _bNeedRefresh = true;
            }
        }
        /// <summary>
        /// 固定减伤
        /// </summary>
        public float Shild_Fixed
        {
            get => _fShild_Fixed;
            set
            {
                _fShild_Fixed = value;

                _bNeedRefresh = true;
            }
        }
        /// <summary>
        /// 百分比减伤
        /// </summary>
        public float Shild_Percent => Mathf.Min(0.8f, _fShild_Percent);


        /// <summary>
        /// 当前血量
        /// </summary>
        public float CurHp => _fCurHp;
        
        /// <summary>
        /// 血量上限
        /// </summary>
        public float MaxHp
        {
            get => _fMaxHp;
            set
            {
                _fMaxHp = Mathf.Max(0, value);

                if (CurHp > _fMaxHp)
                    _fCurHp = _fMaxHp;

                CurHPS_Percent = _fMaxHp * HPS_Percent;

                _bNeedRefresh = true;
            }
        }

        public FortHP(int hp, float hps)
        {
            Reset(hp, hps);
        }

        public void Reset(int hp,float hps)
        {
            _fCurHp = hp;
            _fMaxHp = hp;
            _fHPS_Fixed = hps;

            IsDeath = false;

            _fShild_Fixed = 0;
            _fShild_Percent = 0;
            _fHPS_Percent = 0;
            CurHPS_Percent = 0;
        }

        public void AddHp(float value)
        {
            if (value == 0) return;

            if (value > 0)
            {
                //加血
                _fCurHp = Mathf.Clamp(_fCurHp + value, 0, _fMaxHp);
            }
            else if (value < 0)
            {
                //扣血
                //固定减伤
                value = Mathf.Min(0, value + _fShild_Fixed);
                //减没了
                if (value == 0) return;
                //百分比减伤
                value *= (1- Shild_Percent);

                _fCurHp = Mathf.Clamp(_fCurHp + value, 0, _fMaxHp);
                if (_fCurHp <= 0)
                    Death();
            }
            _bNeedRefresh = true;
        }
        public void AddShild_Percent(float value)
        {
            if (value == 0) return;
            if (value > 1) Debug.LogError("减伤大于1就是全减了");

            if (value > 0)
            {
                /*
                 * 初始减伤 0 初始实际受伤 1
                 * 添加减伤 0.1
                 * 减伤 0.1 实际受伤 0.9
                 * 添加减伤 0.1 (是实际受伤部分的减伤,0.9 的 0.1)
                 * 减伤 0.19 实际受伤 0.81
                 * 添加减伤 0.1 (0.81 的 0.1)
                 * 减伤 0.271 实际受伤 0.729
                 */
                _fShild_Percent = 1 - (1 - _fShild_Percent) * (1 - value);
            }
            else if (value < 0)
            {
                /*
                 * 当前减伤 0.271 当前受伤 0.729
                 * 减伤减少 0.1 (当前受伤还原到减伤前, 0.729 / ( 1 - 0.1 ) = 0.81 )
                 * 减伤 0.19 实际受伤 0.81
                 */
                _fShild_Percent = 1 - (1 - _fShild_Percent) / (1 + value);
            }

            Debug.Log($"AddShild_Percent --- value:{value} - now:{_fShild_Percent}");

            _bNeedRefresh = true;
        }

        public void Refresh(float deltaTime)
        {
            if (IsDeath) return;

            if (CurHp < MaxHp)
            {
                AddHp((_fHPS_Fixed + CurHPS_Percent) * deltaTime);
            }

            if (_bNeedRefresh)
                EventOnHpChange?.Invoke(this);
        }

        public void Death()
        {
            if (IsDeath) return;
            IsDeath = true;
            EventOnDeath?.Invoke();
        }
    }
}
